package proxy;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName JdkDynamicProxy
 * @PackageName proxy
 * @projectName myThread
 * @Description 
 * @Author games
 * @Date 2025/8/29 下午1:24
 * @Version 1.0
 */


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 调用处理器
@Slf4j
class MyInvocationHandler implements InvocationHandler {
    private Object target; // 被代理的对象

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 打印方法执行前的日志，输出方法名称
        log.info("方法执行前: {}", method.getName());

        // 调用目标方法
        Object result = method.invoke(target, args);

        log.info("方法执行后: {}", method.getName());
        return result;
    }
}

// 动态代理工厂
@Slf4j
class ProxyFactory {
    /**
     * 创建一个动态代理对象
     *
     * @param target 目标对象，即被代理的对象
     * @return 返回一个代理对象，该代理对象实现了目标对象的所有接口
     */
    public static Object getProxy(Object target) {
        log.info("创建 {} 类的代理对象", target.getClass().getSimpleName());
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),  // 类加载器：用于加载代理类的类加载器
                target.getClass().getInterfaces(),   // 接口数组：代理对象需要实现的接口列表
                new MyInvocationHandler(target)      // 调用处理器：处理代理对象方法调用的处理器
        );
    }
}

// 使用示例
@Slf4j
public class JdkDynamicProxy {
    /**
     * 主方法，演示静态代理模式的使用
     * 通过ProxyFactory创建代理对象，并调用UserService的方法
     *
     * @param args 命令行参数，本程序中未使用
     */
    public static void main(String[] args) {
        log.info("开始执行JDK动态代理示例");
        // 创建UserService的实现类实例
        StaticProxy.UserService userService = new StaticProxy.UserServiceImpl();
        // 通过ProxyFactory获取userService的代理对象
        StaticProxy.UserService proxy = (StaticProxy.UserService) ProxyFactory.getProxy(userService);
        // 通过代理对象调用addUser方法，添加用户"李四"
        log.info("用户添加完成==: {}", proxy);
        proxy.addUser("李四");
        // 通过代理对象调用getUser方法，获取ID为2的用户信息
        proxy.getUser(2);
        log.info("JDK动态代理示例执行完成");
    }
}
